home *** CD-ROM | disk | FTP | other *** search
- /* _ f l s b u f
- *
- * This file contains three functions: _ioexit, _ioflush()
- * and _flsbuf().
- *
- * _ioexit is empty and just provides a hook by which other
- * functions can force the loading of this module (_ioflush()
- * in particular).
- *
- * _ioflush() flushes all output buffers. This ensures that
- * all streams are written out and closed. It's main purpose
- * is to ensure that all streams are flushed on exit. exit()
- * knows about the existence of _ioflush.
- *
- * _flsbuf allocates and flushes an output buffer. If no buffer
- * has been previously allocated, one will be allocated. This function
- * is intimately tied to the putc() macro in the stdio library.
- *
- * The function returns the character that was written to the
- * file, otherwise EOF on error.
- *
- * Patchlevel 1.2
- *
- * Edit History:
- * 06-Sep-1989 Declare c as unsigned char in _flsbuf().
- * 05-Sep-1989 Change SETCLEANUP to SETIOFLUSH. Add _ioflush()
- * and _ioexit().
- */
-
- #include "stdiolib.h"
-
- /*LINTLIBRARY*/
-
- void _ioexit()
-
- {
- }
-
- void _ioflush()
-
- {
- int i; /* slot index */
-
- for (i = 0; i < _NFILE; i++)
- if (_iop[i] != NULL)
- (void) fclose(_iop[i]);
- }
-
- #ifdef __STDC__
- int _flsbuf(unsigned char c, FILE *fp)
- #else
- int _flsbuf(c, fp)
- unsigned char c; /* character to write */
- FILE *fp; /* stream */
- #endif
- {
- char valid; /* character still valid */
- int length; /* length of write */
- int write(); /* write to channel */
-
- if (TESTFLAG(fp, _IOSTRING))
- return (unsigned char) (*fp->_ptr++ = c);
-
- if (GETFLAG(fp, _IORW | _IOWRITE) == _IORW) {
- if (! TESTFLAG(fp, _IOREAD))
- SETFLAG(fp, _IOWRITE);
- else {
- if (TESTFLAG(fp, _IOEOF))
- TOGGLEFLAG(fp, (_IOEOF | _IOREAD | _IOWRITE));
- }
- }
-
- if (GETFLAG(fp, (_IOWRITE | _IOERR)) != _IOWRITE)
- return EOF;
-
- if (! HASBUFFER(fp)) {
- if (_allocbuf(fp) < 0)
- return EOF;
- SETIOFLUSH();
- }
-
- /* Signal character valid if fully buffered output */
- if (! TESTFLAG(fp, (_IONBF | _IOLBF)))
- valid = 1;
-
- /* Do the write here if unbuffered or line buffered */
- else {
- if (TESTFLAG(fp, _IONBF)) {
- *fp->_ptr++ = c;
- valid = 0;
- }
- else if (fp->_ptr < fp->_base + fp->_bufsiz) {
- if ((*fp->_ptr++ = c) == '\n')
- valid = 0;
- else
- return (unsigned char) c;
- }
- else
- valid = 1;
- }
-
- /* Flush the current buffer load */
- if ((length = fp->_ptr - fp->_base) != 0 &&
- write(fp->_file, (char *) fp->_base, length) != length) {
- SETFLAG(fp, _IOERR);
- FLUSHNEXTWRITE(fp);
- return EOF;
- }
-
- /* Reset the buffer pointers --- unbuffered => not valid */
- INITWRITEBUFFER(fp);
- if (valid)
- *fp->_ptr++ = c;
-
- return (unsigned char) c;
- }
-